Un base de données (BDD) permet l’enregistrement de données dans un format organisé et hiérarchisé.
La durée de vie des données stockées dans des variables PHP est limitée au temps d’éxécution du script.
Il est aussi possible de stocker des données dans des fichiers externes, mais cette solution n’est pas viable pour une grande quantité de données.
Pour manipuler une BDD, on utilise un SGBD.
C’est un Système de Gestion de Base de Données.
Comme son nom l’indique, un SGBD permet :
La plupart des SGBD utilisent le langage SQL (Structured Query Language).
Les données brutes sont stockées dans des fichiers sur le serveur. Le SGBD a pour mission de permettre leur accès en optimisant les opération de lecture/écriture.
Il existe plusieurs SGBD; parmi les plus utilisés on retrouve :
Dans ce cours, nous travaillerons avec MySQL. Il est le SGBD libre et gratuit le plus utilisé (mais pas le seul).
Note
Dans ce schéma, vous pourriez remplacer PHP par n’importe quel langage dédié à la gestion de pages web dynamiques. De même, MySQL pourrait très bien être remplacé par un autre SGBD, tant que le langage qui utilisé de PHP au SGBD reste le SQL.
Une base de données est composée de tables.
Chaque table est composée de champs.
Chaque champ contient plusieurs valeurs.
Chaque entrée ou enregistrement correspond à ensemble comprenant une valeur pour chaque champ.
Astuce
Généralement, on crée une base de donnée spécifique à chaque site web. Mais il est aussi possible de partager une même base entre plusieurs sites.
On peut voir une table comme un tableau de la forme :
Identifiant | Champ1 | Champ2 | ... |
---|---|---|---|
1 | Valeur11 | Valeur21 | ... |
2 | Valeur12 | Valeur22 | ... |
3 | Valeur13 | Valeur23 | ... |
... | ... | ... | ... |
Astuce
Le champ identifiant n’est pas obligatoire, mais il permet d’affecter une valeur unique à chaque enregistrement. L’utilisation d’identifiants permet aussi de lier les données de plusieurs tables entre-elles.
Pour faciliter les opérations de gestion des bases de données, il existe un outil nommé PhpMyAdmin, qui propose une interface de gestion Web des BDD sous la forme de pages PHP permettant (entre autres) :
Depuis un serveur local (type WAMP) : http://localhost/phpMyAdmin
L’objectif de cet exercice est de se familiariser avec l’interface PhpMyAdmin.
Instructions :
Avant de pouvoir lire ou écrire dans une base de données, il est nécessaire de s’y connecter.
La connexion à une base de données est un processus d’authentification qui permet de s’assurer que seuls les utilisateurs autorisés peuvent accéder aux données et/ou les modifier.
Les SGBD utilisent un vocabulaire spécifique relatif au processus de connexion :
PHP propose plusieurs fonctionnalités intégrées pour se connecter à une base de données via un SGBD. Les évolutions successives de PHP explique l’existance de 3 exentions :
En conclusion, PDO est une solution générique qui permettra d’utiliser le même code pour dialoguer avec les différents SGBD. C’est aussi une version optimisée qui utilise les fonctionnalités avancées des dernières versions de PHP (nottament la programmation orientée objet).
Fonction de connexion :
<?php
function Connect_db(){
$host="localhost"; // ou sql.hebergeur.com
$user="root"; // ou login
$password=""; // ou xxxxxx
$dbname="nom_bdd";
try {
$bdd=new PDO('mysql:host='.$host.';dbname='.$dbname.
';charset=utf8',$user,$password);
return $bdd;
} catch (Exception $e) {
die('Erreur : '.$e->getMessage());
}
}
?>
Après s’être connecté à une base de données, il est possible d’accéder à son contenu, en suivant le protocole suivant :
Les requêtes sont interprétées par le SGBD, elles sont dont formulées dans le langage qu’il manipule, c’est à dire le SQL.
Le langage SQL est dédié à l’écriture de requêtes. Sa syntaxe, sous forme de chaîne de caractères, permet de créer des requêtes complexes à partir de quelques mots clés.
Le langage SQL est articulé autour de mots-clés facilement interprétables, exemple :
L’ordre des mots-clés est figé, mais il n’est pas obligatoire de tous les utiliser.
Un exemple d’une requête de lecture complète pourrait être :
SELECT champ1, champ2, champ3
FROM table
WHERE champ1='valeur'
AND champ2 < 20
OR champ 3 > 0
ORDER BY champ2 DESC, champ3 ASC
LIMIT 0,5
Astuce
Le sélecteur * permet de sélectionner tous les champs d’une table : SELECT *.
D’autres mots-clés permettent d’ajouter/modifier/supprimer un enregistrement dans une table.
Exemple d’insertion :
INSERT INTO table(champ1,champ2, champ3)
VALUES (valeur1, valeur2, valeur3)
Avertissement
Les SGBD sont très sécurisés au niveau des requêtes d’insertion. Aussi, la requête se traduira systématiquement par un échec dans le cas d’oubli d’un des champs ou de types de paramètres incompatibles.
Toutes les vérifications devront êtres faites côté PHP avant génération de la requête SQL.
Note
Si un champ de la table à été déclaré comme une clé primaire (identifiant) avec la propriété auto_increment, il n’est pas nécessaire de faire apparaître ce champ ni sa valeur dans une requête d’insertion.
Exemple de modification :
UPDATE table SET champ2 = valeur2, champ3 = valeur3
WHERE champ1 = valeur1
Avertissement
Les requêtes de modifications utilisent aussi une partie sélection.
La requête n’aboutiera pas si la condition du WHERE n’est pas satisfaisable.
Note
Il est possible de modifier plusieurs enregistrements en une seule requête : c’est la condition de sélection qui fait la différence.
Exemple de suppression :
DELETE FROM table WHERE champ1=valeur1
Avertissement
Les suppressions ne sont pas annulables.
Attention : sans la condition WHERE tous les enregistrements de la table seront supprimés !
Depuis PhpMyAdmin, il est possible de taper directement des requêtes SQL et d’afficher le résultat retourné.
La lecture de données depuis une BDD s’exécute suivant ce protocole :
1 2 3 4 5 6 7 8 9 10 | <?php
$bdd = Connect_db(); //connexion à la BDD
$query = $bdd->prepare('...'); // requête SQL
$query->execute(...); // paramètres et exécution
while($data = $query->fetch()) { // lecture par ligne
... // traitement de l'enregistrement
} // fin des données
$query->closeCursor();
?>
|
Quelques remarques :
Avertissement
Une faille connue nommée “injection SQL” peut être exploitée lorsque l’on utilise des données entrées par l’utilisateur dans des requêtes SQL. Afin d’éviter que d’autres requêtes soient injectées dans les variables via PHP, il faut TOUJOURS utiliser les fonctions prepare() et execute().
1 2 3 4 5 6 | <?php
...
$query=$bdd->prepare('SELECT * from table');
$query->execute();
...
?>
|
Note
Pour gagner du temps, il est aussi possible d’utiliser la fonction exec() qui prend en paramètre une requête, et s’applique sur l’objet BDD :
$query=$bdd->exec('...');.
Attention : n’utilisez la fonction exec() que si la requête ne comporte pas de paramètres (pas de variables PHP) pour éviter la faille d’injection SQL.
1 2 3 4 5 6 7 8 9 10 | <?php
...
$query=$bdd->prepare('SELECT champ1, champ2
FROM table
WHERE champ1 = ?
AND champ3 <= ?
ORDER BY champ2');
$query->execute(array($valeur1, $valeur2));
...
?>
|
1 2 3 4 5 6 7 8 9 10 11 | <?php
...
$query=$bdd->prepare('SELECT champ1, champ2
FROM table
WHERE champ1 = :valeur1
AND champ3 <= :valeur2
ORDER BY champ2');
$query->execute(array('valeur1' => $valeur1,
'valeur2' => $valeur2));
...
?>
|
L’écriture de données dans une BDD se fait en suivant les étapes suivantes :
Trois actions sont possibles pour l’écriture : insertion, modification ou suppression d’un enregistrement.
Avec paramètres :
1 2 3 4 5 | <?php
$bdd = Connect_db(); //connexion à la BDD
$query = $bdd->prepare('...'); // requête SQL
$query->execute(...); // paramètres et exécution
?>
|
Sans paramètres :
1 2 3 4 | <?php
$bdd = Connect_db(); //connexion à la BDD
$query = $bdd->exec('...'); // requête SQL
?>
|
Note
Pour effectuer chacune des opérations (ajout, modification, suppression), il suffit de choisir la bonne requête (INSERT INTO, UPDATE SET, DELETE FROM);
Un des intérêts majeurs des BDD est de pouvoir lier des données entre-elles afin de leur donner une sémantique plus forte.
L’utilisation d’identifiants uniques (clés primaires) pour chaque enregistrement, permet leur réutilisation dans d’autres tables. On les appelle alors des clés secondaires (ou clés étrangères).
Exemple, table “Films”:
ID_FILM | TITRE_FILM | ANNEE_FILM | ... |
---|---|---|---|
1 | Titanic | 1997 | ... |
2 | Star Wars | 1977 | ... |
3 | Braveheart | 1995 | ... |
... | ... | ... | ... |
Exemple, table “Acteurs”:
ID_ACTEUR | NOM_ACTEUR | PRENOM_ACTEUR | ... |
---|---|---|---|
1 | Di Caprio | Leonardo | ... |
2 | Winslet | Kate | ... |
3 | Gibson | Mel | ... |
... | ... | ... | ... |
Les champs ID_FILM et ID_ACTEUR sont les clés primaires de leurs tables respectives.
Exemple de table de jointure, table “Casting” :
ID_FILM | ID_ACTEUR |
---|---|
1 | 1 |
1 | 2 |
2 | 3 |
... | ... |
Ici, les champs ID_FILM et ID_ACTEUR deviennent clés étrangères et permettent de lier les tables “Acteurs” et “Films”.
Pour pouvoir accéder aux données présentes dans des tables jointes de la sorte, il faut utiliser les requêtes de jointure.
Les alias :
Pour écrire une requête qui intervenant sur plusieurs tables jointes, il est possible de simplifier l’écriture en définissant des alias.
Deux écritures sont possibles après la clause FORM :
SELECT *
FROM table AS alias
Ou
SELECT *
FROM table t
Note
La première version reste la plus lisible.
Notez que par convention, les noms des tables s’écrivent en minuscules. Une bonne pratique est de conserver ce format mais de réduire leur taille en utilisant des alias.
Les requêtes de jointure s’écrivent en utilisant le mot clé INNER JOIN ... ON. La clause ON permet de définir la condition de la jointure (c’est à dire la correspondance entre les clés primaires/étrangères).
Exemple :
SELECT *
FROM table1
INNER JOIN table2
ON table1.ID_CHAMP1 = table2.ID_CHAMP2
Astuce
On peut bien sûr imbriquer plusieurs jointures lorsque plus de deux tables sont liées. Pour cela, il suffit de préciser les conditions de jointures les unes après les autres (INNER JOIN ... ON ... INNER JOIN ... ON).